package com.iafme.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.iafme.dto.req.CertificateOrderReqDTO;
import com.iafme.dto.res.CertificateOrderResDTO;
import com.iafme.dto.res.OrderResDTO;
import com.iafme.mapper.CertificateOrderMapper;
import com.iafme.model.CertificateOrder;
import com.iafme.properties.PayProperties;
import com.iafme.properties.ScanPayReq;
import com.iafme.service.CertificateOrderService;
import com.iafme.service.OrderNoTypeService;
import com.iafme.service.RedemptionService;
import com.iafme.utils.AdmissionNumUtil;
import com.systemframework.constants.Constants;
import com.systemframework.exception.ResultException;
import com.systemframework.pay.model.PayOrderRequestDTO;
import com.systemframework.pay.service.impl.AlPay;
import com.systemframework.pay.service.impl.WxPay;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

/**
 * @author summer
 * @version 1.0
 * @date 2025/3/25 18:51
 */
@Service
@Transactional(rollbackFor = Exception.class)
@AllArgsConstructor
public class CertificateOrderServiceImpl extends ServiceImpl<CertificateOrderMapper, CertificateOrder> implements CertificateOrderService {
    @Override
    public OrderResDTO updateStatus(String outTradeNo) {
        LambdaQueryWrapper<CertificateOrder> eq = Wrappers.lambdaQuery(CertificateOrder.class).eq(CertificateOrder::getOrderNo, outTradeNo);
        CertificateOrder certificateOrder = this.getOne(eq);
        if(certificateOrder.getStatus().equals(Constants.ZERO)){
            certificateOrder.setStatus(Constants.ONE);
            certificateOrder.setAuthorization(Constants.ONE);
            certificateOrder.setPayTime(LocalDateTime.now());
            this.updateById(certificateOrder);
        }
        OrderResDTO resDTO = new OrderResDTO();
        resDTO.setOrderNo(outTradeNo);
        return resDTO;
    }

    @Override
    public void cancelOrder(CertificateOrderReqDTO reqDTO) {
        CertificateOrder order = this.getById(reqDTO.getId());
        if(ObjectUtil.isEmpty(order)){
            throw new ResultException("证书申请订单不存在");
        }
        order.setStatus(reqDTO.getStatus());
        this.updateById(order);
    }

    private final WxPay wxPay;

    private final AlPay alPay;

    private final PayProperties payProperties;

    private final RedemptionService redemptionService;
    private final OrderNoTypeService orderNoTypeService;


    @Override
    public ScanPayReq payOrder(CertificateOrderReqDTO reqDTO, HttpServletRequest request) {
        ScanPayReq scanPayReq = new ScanPayReq();
        CertificateOrder order = this.getById(reqDTO.getId());
        if(ObjectUtil.isEmpty(order)){
            throw new ResultException("证书申请订单不存在");
        }
        order.setPayType(reqDTO.getPayType());
        String code="";
        if (reqDTO.getPayType().equals(3)){
                redemptionService.checkRedemption(reqDTO.getCode());
                this.updateById(order);
                this.updateStatus(order.getOrderNo());
                scanPayReq.setCodeUrl("");
                scanPayReq.setOrderNo(order.getOrderNo());
                return  scanPayReq;

        }
            String orderNo = AdmissionNumUtil.orderNum();
            orderNoTypeService.updateOrderType(order.getOrderNo(),orderNo);
            order.setOrderNo(orderNo);
            PayOrderRequestDTO payOrderRequestDTO=new PayOrderRequestDTO();
            payOrderRequestDTO.setOrderNo(order.getOrderNo());
            payOrderRequestDTO.setProductPrice(order.getAmount().toString());
            payOrderRequestDTO.setProductName(order.getDetails());
            payOrderRequestDTO.setProductId(order.getId().toString());
            if(reqDTO.getPayType().equals(Constants.ONE)){
                payOrderRequestDTO.setNotifyUrl(payProperties.getWxNotifyUrl());
                code=wxPay.nativePay(payOrderRequestDTO, request);
            }else if(reqDTO.getPayType().equals(Constants.TWO)){
                payOrderRequestDTO.setNotifyUrl(payProperties.getAliNotifyUrl());
                code=alPay.nativePay(payOrderRequestDTO, request);
            }



        this.updateById(order);
        scanPayReq.setCodeUrl(code);
        scanPayReq.setOrderNo(order.getOrderNo());
        return scanPayReq;
    }
}
